(define (domain tropos-domain)

	(:requirements :adl :fluents :derived-predicates)

	(:types t_actor t_goal t_gtype)

	(:predicates
  
		(satisfied ?g - t_goal)
		(can_provide ?a - t_actor ?g - t_goal)
		(requests ?a - t_actor ?g - t_goal)
		(can_depend_on ?a1 ?a2 - t_actor)
		(and_subgoal2 ?g ?g1 ?g2 - t_goal)
		(and_subgoal3 ?g ?g1 ?g2 ?g3 - t_goal)
		(or_subgoal2 ?g ?g1 ?g2 - t_goal)
		(or_subgoal3 ?g ?g1 ?g2 ?g3 - t_goal)
		(is_means_end ?g1 ?g2 - t_goal)


		(subtype ?child ?parent - t_gtype)
		(type ?g - t_goal ?gt - t_gtype)
		(can_depend_on_gt ?a1 ?a2 - t_actor ?gt - t_gtype)
		(can_depend_on_g ?a1 ?a2 - t_actor ?g - t_goal)
		(can_decompose_gt ?a - t_actor ?gt - t_gtype)
		(can_provide_gt ?a - t_actor ?gt - t_gtype) 

		(pr_satisfies ?a - t_actor ?g - t_goal)
		(pr_and_decomposes2 ?a - t_actor ?g ?g1 ?g2 - t_goal)
		(pr_and_decomposes3 ?a - t_actor ?g ?g1 ?g2 ?g3 - t_goal)

		(pr_or_decomposes2 ?a - t_actor ?g ?g1 ?g2 - t_goal)
		(pr_or_decomposes3 ?a - t_actor ?g ?g1 ?g2 ?g3 - t_goal)
		(pr_passes ?a1 ?a2 - t_actor ?g - t_goal)
  
	)

;; functions

	(:functions
		; metric properties
		(satisfaction_coeff) ; contribution factor of total_satisfaction_degree in the final plan quanlity
		(work_load_coeff) ; contribution factor of total_work_load in the final plan quanlity
		(rt_total_satisfaction_degree) ; [RT] the total satisfaction degree of all goals.
		(rt_total_work_load) ; [RT]  the total work load of all actors to finish all goals (Overral plan cost).
		(rt_plan_quality)	; [RT] the final metric of a given solution, computed as
						;		plan_quality = satisfaction_coeff * total_satisfaction - work_load_coeff * total_work_load - [Solution-Length]*0.1
						;  

		; goal properties
		(expected_satisfaction_degree ?g - t_goal) 
		;(load ?g - t_goal) ; workload for a goal
		(rt_satisfaction_degree ?g - t_goal)  ; [RT] specify current satisfaction level of all goals
		
		; actor properties
		(max_work_load ?a - t_actor)  ; maximum workload of an actor
		(max_job_at_hand ?a - t_actor) 
		(satisfaction_ability ?a - t_actor ?g - t_goal) 
		;100 = excellent, 75 = good, 50 = average, 25 = low, 0 = not provide

		;(extra_work_effort ?a - t_actor ?g - t_goal) ; an additional efforts paid by actor for doing the given goal 

		(work_effort ?a - t_actor ?g - t_goal) 
		;100 = innocent ; 75 = has some knowledge; 50 = has good knowledge/trained; 25 = well-trained

		(rt_work_load ?a - t_actor)  ; [RT] current workload of an actor
		(rt_job_at_hand ?a - t_actor) ; [RT]

		
		
	)
;; derived predicates

	(:derived (can_depend_on_g ?r ?p - t_actor ?g - t_goal)
		(and
			(requests ?r ?g)
			(can_provide ?p ?g)
		)
	)i

;; normal actions
	
	(:action Satisfies
        :parameters( ?a - t_actor ?g - t_goal )
        :precondition (and
			(not (satisfied ?g))
			(not (pr_satisfies ?a ?g))
			(can_provide ?a ?g)
			(requests ?a ?g )
			(<= (+ (rt_work_load ?a) (work_effort ?a ?g)) (max_work_load ?a))
			(< (rt_job_at_hand) (max_job_at_hand))
        )
        :effect( and
			(satisfied ?g)
			(not (requests ?a ?g) )
			(pr_satisfies ?a ?g)

			; actor effect
			(increase (rt_work_load ?a) (work_effort ?a ?g))
			(increase (rt_job_at_hand ?a) 1)

			;(increase (satisfaction_degree ?g) (satisfaction_ability ?a ?g))
			;(increase (rt_total_satisfaction_degree) (satisfaction_ability ?a ?g))
			;(increase (total_work_load) (+ (load ?g) (extra_work_effort ?a ?g)))
			;(increase (rt_total_work_load) (work_effort ?a ?g))
			;(assign (rt_plan_quality) (- (* (satisfaction_coeff) (rt_total_satisfaction_degree)) (* (work_load_coeff) (rt_total_work_load))))
			(increase (rt_plan_quality) (- (* (satisfaction_coeff) (satisfaction_ability ?a ?g)) (* (work_load_coeff) (work_effort ?a ?g))))
			;(increase (plan_quality) (- (* (satisfaction_coeff) (satisfaction_ability ?a ?g)) (* (work_load_coeff) (+ (load ?g) (extra_work_effort ?a ?g))) ) )

		)
	)
    
	(:action Means_End
        :parameters (?p ?r - t_actor ?g1 ?g2 - t_goal)
        :precondition ( and
             (is_means_end ?g1 ?g2)
             (pr_satisfies ?p ?g1)
             (requests ?r ?g2)
             (satisfied ?g1)
        )
        :effect ( and 
             (satisfied ?g2)
             (not (requests ?r ?g2))
        )
    )

    (:action AND_Decomposes2
        :parameters( ?a - t_actor ?g ?g1 ?g2 - t_goal )
        :precondition( and
            (and_subgoal2 ?g ?g1 ?g2 )
            (requests ?a ?g)
        )
        :effect( and
            (requests ?a ?g1)
            (requests ?a ?g2)
            (not (requests ?a ?g) )
            (pr_and_decomposes2 ?a ?g ?g1 ?g2)
            )
    )

    (:action AND_Decomposes3
        :parameters( ?a - t_actor ?g ?g1 ?g2 ?g3 - t_goal )
        :precondition( and
            (and_subgoal3 ?g ?g1 ?g2 ?g3 )
            (requests ?a ?g)
        )
        :effect( and
            (requests ?a ?g1)
            (requests ?a ?g2)
            (requests ?a ?g3)
            (not (requests ?a ?g) )
            (pr_and_decomposes3 ?a ?g ?g1 ?g2 ?g3)
            )
    )
  
    (:action OR_Decomposes2
        :parameters( ?a - t_actor ?g ?g1 ?g2 - t_goal )
        :precondition( and
            (or_subgoal2 ?g ?g1 ?g2 )
            (requests ?a ?g)
        )
        :effect( and
            (requests ?a ?g1)
            (requests ?a ?g2)
            (not (requests ?a ?g) )
            (pr_or_decomposes2 ?a ?g ?g1 ?g2)
            )
    )

    (:action OR_Decomposes3
        :parameters( ?a - t_actor ?g ?g1 ?g2 ?g3 - t_goal )
        :precondition( and
            (or_subgoal3 ?g ?g1 ?g2 ?g3 )
            (requests ?a ?g)
        )
        :effect( and
            (requests ?a ?g1)
            (requests ?a ?g2)
            (requests ?a ?g3)
            (not (requests ?a ?g) )
            (pr_or_decomposes3 ?a ?g ?g1 ?g2 ?g3)
            )
    )

    (:action Passes
        :parameters( ?a1 ?a2 - t_actor ?g - t_goal )
        :precondition( and
            (not (exists (?delegatee - t_actor) (pr_passes ?a2 ?delegatee ?g) ) )   
            (requests ?a1 ?g)
            (or (can_depend_on ?a1 ?a2)
                (can_depend_on_g ?a1 ?a2 ?g)
                (exists (?gt - t_gtype) (and (type ?g ?gt) (can_depend_on_gt ?a1 ?a2 ?gt) ) ) 
            )
         )
        :effect( and
			
            (requests ?a2 ?g)
            (not (requests ?a1 ?g) )
            (pr_passes ?a1 ?a2 ?g)
            )
    )

    (:action CombinesAnd2  
         :parameters( ?g ?g1 ?g2 - t_goal )
         :precondition( and
            (and_subgoal2 ?g ?g1 ?g2 )
            (satisfied ?g1)
            (satisfied ?g2)
         )
         :effect (satisfied ?g )
    )

    (:action CombinesAnd3  
         :parameters( ?g ?g1 ?g2 ?g3 - t_goal )
         :precondition( and
            (and_subgoal3 ?g ?g1 ?g2 ?g3 )
            (satisfied ?g1)
            (satisfied ?g2)
            (satisfied ?g3)
         )
         :effect(and (satisfied ?g ))
    )

    (:action CombinesOr2  
         :parameters( ?g ?g1 ?g2 - t_goal )
         :precondition( and
            (or_subgoal2 ?g ?g1 ?g2 )
            (or (satisfied ?g1)  (satisfied ?g2))
         )
         :effect (satisfied ?g )
    )

    (:action CombinesOr3  
         :parameters( ?g ?g1 ?g2 ?g3 - t_goal )
         :precondition( and
            (or_subgoal3 ?g ?g1 ?g2 ?g3)
            (or (satisfied ?g1)  (satisfied ?g2) (satisfied ?g3))
         )
         :effect (satisfied ?g )
    )

)